package com.zikao.article.controller;

import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zikao.article.entity.*;
import com.zikao.article.service.*;
import com.zikao.article.vo.RemarkVo;
import com.zikao.article.vo.ReplyVo;
import com.zikao.article.vo.TableListVo;
import com.zikao.common.exception.RRException;
import com.zikao.user.entity.UserEntity;
import com.zikao.user.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import com.zikao.common.utils.PageUtils;
import com.zikao.common.utils.R;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author likaisheng
 * @email 1805318928@qq.com
 * @date 2021-02-21 10:55:38
 */
@Controller
@RequestMapping("article/article")
@Slf4j
public class ArticleController {
    @Autowired
    private ArticleService articleService;
    @Autowired
    private TagService tagService;
    @Autowired
    private RemarkService remarkService;
    @Autowired
    private ReplyService replyService;
    @Autowired
    private UserService userService;
    @Autowired
    private PraiseService praiseService;
    @Autowired
    private CollectService collectService;

    /**
     * 写文章页面
     * @param model
     * @return
     */
    @GetMapping("writeArticle")
    public String writeArticle(Model model) {
        List<TagEntity> tags = tagService.selectByMap(new HashMap<String, Object>());
        model.addAttribute("tags", tags);
        return "writeArticle";
    }
    /**
     * 编辑文章页面
     * @param model
     * @return
     */
    @GetMapping("editArticle/{id}")
    public String editArticle(@PathVariable("id") Long id,Model model,HttpServletRequest request,HttpServletResponse response) {
        UserEntity user = (UserEntity) request.getSession().getAttribute("user");
        ArticleEntity article = articleService.getArticleById(id);
        if (article.getIsPublish() == 1){
            throw new RRException("抱歉发生了错误，请勿乱操作");
        }else if (article.getUserId() != user.getId()){
            throw new RRException("抱歉发生了错误，请勿乱操作");
        }
        List<TagEntity> tags = tagService.selectByMap(new HashMap<String, Object>());
        model.addAttribute("tags", tags);
        model.addAttribute("article",article);
        return "editArticle";
    }

    /**
     * 浏览文章
     * @return
     */
    @GetMapping("showArticle/{id}")
    public String showArticle(@PathVariable("id") Long id,Model model) {
        try{
            // 获取点赞数
            QueryWrapper<PraiseEntity> praisewrapper = new QueryWrapper<>();
            praisewrapper.eq("article_id",id);
            int praiseNum = praiseService.count(praisewrapper);
            // 获取收藏数
            QueryWrapper<CollectEntity> collectwrapper = new QueryWrapper<>();
            collectwrapper.eq("article_id",id);
            int collectNum = collectService.count(collectwrapper);
            // 获取评论数
            QueryWrapper<RemarkEntity> remarkwrapper = new QueryWrapper<>();
            remarkwrapper.eq("article_id",id);
            int remarkNum = remarkService.count(remarkwrapper);

            // 获取评论
            Map<String,Object> remarkParams = new HashMap<>();
            remarkParams.put("article_id",id);
            List<RemarkEntity> remarkList = remarkService.selectByParams(remarkParams);

            List<RemarkVo> remarkVos = new LinkedList<>();
            if(remarkList.size()>0){
                // 获取回复
                List<Long> remarkIds = remarkList.stream().map(r -> {
                    return r.getId();
                }).collect(Collectors.toList());
                List<ReplyEntity> replyList = replyService.selectBatchByRemarkIds(remarkIds);

                // 获取评论人、回复人信息
                List<Long> remarkUserIds = remarkList.stream().map(r -> {
                    return r.getUserId();
                }).collect(Collectors.toList());
                List<Long> replyUserIds = replyList.stream().map(r->{
                    return r.getUserId();
                }).collect(Collectors.toList());
                List<Long> userIds = new LinkedList<>();
                userIds.addAll(remarkUserIds);
                userIds.addAll(replyUserIds);
                List<UserEntity> userList = userService.selectBatchIds(userIds);
                Map<Long, UserEntity> userMap = userList.stream().collect(Collectors.toMap(v -> v.getId(), v -> v));

                // 拼装数据 一个评论可以有多条回复
                Map<Long, List<ReplyVo>> replyMap = new HashMap<>();
                for (ReplyEntity reply : replyList){
                    if (replyMap.get(reply.getRemarkId()) == null){
                        List<ReplyVo> replyVos = new LinkedList<>();
                        ReplyVo replyVo = new ReplyVo();
                        replyVo.setReply(reply);
                        replyVo.setUser(userMap.get(reply.getUserId()));
                        replyVos.add(replyVo);
                        replyMap.put(reply.getRemarkId(),replyVos);
                    }else {
                        ReplyVo replyVo = new ReplyVo();
                        replyVo.setReply(reply);
                        replyVo.setUser(userMap.get(reply.getUserId()));
                        replyMap.get(reply.getRemarkId()).add(replyVo);
                    }
                }

                // 拼装返回数据
                remarkVos = remarkList.stream().map((v) -> {
                    RemarkVo remark = new RemarkVo();
                    remark.setRemark(v);
                    remark.setUser(userMap.get(v.getUserId()));
                    return remark;
                }).collect(Collectors.toList());
                for (RemarkVo remarkVo : remarkVos){
                    List<ReplyVo> replyVos = replyMap.get(remarkVo.getRemark().getId());
                    remarkVo.setReplyVos(replyVos);
                }
            }

            // 返回数据
            model.addAttribute("remarkVos",remarkVos);
            model.addAttribute("articleId",id);
            model.addAttribute("praiseNum",praiseNum);
            model.addAttribute("collectNum",collectNum);
            model.addAttribute("remarkNum",remarkNum);
        }catch (Exception e){
            log.error("程序出现错误-showArticle",e);
            throw new RRException("程序出现错误，请联系管理员",500);
        }
        return "showArticle";
    }

    /**
     * 获取今日推荐列表
     * 按今日浏览选10篇
     */
    @RequestMapping("/recommends")
    @ResponseBody
    public List<ArticleEntity> recommends(@RequestParam Map<String, Object> params){
        List<ArticleEntity> articleList = null;
        try{
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.gt("pv",0);
            wrapper.orderByDesc("pv");
            wrapper.last("limit 10");
            articleList = articleService.selectList(wrapper);
        }catch (Exception e){
            log.error("程序发生错误-recommends",e);
            throw new RRException("程序发生错误",500);
        }
        return articleList;
    }

    /**
     * 获取热门文章列表
     * 按总浏览量选10篇
     */
    @RequestMapping("/hots")
    @ResponseBody
    public List<ArticleEntity> hots(@RequestParam Map<String, Object> params){
        List<ArticleEntity> articleList = null;
        try{
            QueryWrapper wrapper = new QueryWrapper();
            wrapper.orderByDesc("total_pv");
            wrapper.last("limit 10");
            articleList = articleService.selectList(wrapper);
        }catch (Exception e){
            log.error("程序发生错误-recommends",e);
            throw new RRException("程序发生错误",500);
        }
        return articleList;
    }

    /**
     * 列表 for layui
     * 用于显示文章列表
     */
    @RequestMapping("/listForLayUI")
    @ResponseBody
    public TableListVo listForLayUI(@RequestParam Map<String, Object> params){
        TableListVo<ArticleEntity> tableListVo = new TableListVo();

        try{
            // 处理搜索功能
            String searchStr = (String) params.get("searchStr");
            QueryWrapper<ArticleEntity> queryWrapper = new QueryWrapper<>();
            if (StringUtils.isNotBlank(searchStr)){
                // 处理搜索框输入
                // 按照空格截取字符串
                String[] strArr = searchStr.split(" ");
                for (int i = 0; i < strArr.length-1;i++){
                    queryWrapper.like("title",strArr[i]);
                    queryWrapper.or();
                }
                queryWrapper.like("title",strArr[strArr.length-1]);
            }

            // 是否发布
            String isPublishStr = (String) params.get("isPublish");
            if (StringUtils.isNotBlank(isPublishStr)){
                Integer is_publish = Integer.parseInt(isPublishStr);
                queryWrapper.eq("is_publish",is_publish);
            }else{
                queryWrapper.eq("is_publish",1);
            }
            // 是否传入了用户id
            String userIdStr = (String) params.get("userId");
            if (StringUtils.isNotBlank(userIdStr)){
                Long userId = Long.parseLong(userIdStr);
                queryWrapper.eq("user_id",userId);
            }

            // 处理文章标签
            String tagIdStr = (String) params.get("tagId");
            if (StringUtils.isNotBlank(tagIdStr)){
                Long tagId = Long.parseLong(tagIdStr);
                queryWrapper.eq("tag_id",tagId);
            }

            // 设置按修改时间排序
            queryWrapper.orderByDesc("update_time");

            PageUtils pageUtils = articleService.queryPage(params,queryWrapper);
            tableListVo.setCode(0);
            tableListVo.setMsg("");
            tableListVo.setCount(pageUtils.getTotalCount());

            List<ArticleEntity> articleList = (List<ArticleEntity>) pageUtils.getList();
            List<Long> userIds = articleList.stream().map(r -> {
                return r.getUserId();
            }).collect(Collectors.toList());

            if(articleList.size()>0){
                List<UserEntity> userList = userService.selectBatchIds(userIds);
                Map<Long, UserEntity> userMap = userList.stream().collect(Collectors.toMap(v -> v.getId(), v -> v));
                for(ArticleEntity article : articleList){
                    UserEntity user = userMap.get(article.getUserId());
                    article.setUserName(user.getName());
                }
            }
            tableListVo.setData(articleList);
        }catch (Exception e){
            log.error("程序发生错误-listForLayUI",e);
            throw new RRException("程序发生错误",500);
        }
        return tableListVo;
    }

    /**
     * 统计pv
     */
    @RequestMapping("/statistics/pv/{id}")
    @ResponseBody
    public R statisticsPv(@PathVariable("id") Long id){
        try{
            ArticleEntity article = articleService.getById(id);
            Integer curPv = Optional.ofNullable(article.getPv()).orElse(0);
            Integer curTotalPv = Optional.ofNullable(article.getTotalPv()).orElse(0);
            article.setPv(curPv + 1);
            article.setTotalPv(curTotalPv + 1);
            articleService.updateById(article);
        }catch (Exception e){
            log.error("程序发生错误-statisticsPv:",e);
            return R.error();
        }
        return R.ok();
    }

    /**
     * 列表
     */
    @RequestMapping("/list")
    @ResponseBody
    public R list(@RequestParam Map<String, Object> params){
        PageUtils page = articleService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @RequestMapping("/info/{id}")
    @ResponseBody
    public R info(@PathVariable("id") Long id){
        ArticleEntity article = null;
        try{
            article = articleService.getArticleById(id);
            // 获取作者信息
            UserEntity user = userService.getById(article.getUserId());
            article.setUserName(user.getName());
        }catch (Exception e){
            log.error("程序出现错误-info",e);
            return R.error("数据读取错误");
        }

        return R.ok().put("article", article);
    }

    /**
     * 保存
     */
    @RequestMapping("/save")
    @ResponseBody
    public R save(@RequestBody ArticleEntity article,HttpServletRequest request,HttpServletResponse response){

        try {
            UserEntity user = (UserEntity) request.getSession().getAttribute("user");
            article.setUserId(user.getId());
            article.setPv(0);
            article.setTotalPv(0);
            articleService.saveArticle(article);
        }catch (Exception e){
            log.error("程序发生错误-save",e);
            return R.error("保存失败");
        }
        return R.ok();
    }

    /**
     * 修改
     */
    @RequestMapping("/update")
    @ResponseBody
    public R update(@RequestBody ArticleEntity article){
		articleService.updateArticleById(article);
        return R.ok();
    }

    /**
     * 删除
     */
    @RequestMapping("/delete")
    @ResponseBody
    public R delete(@RequestBody Long[] ids){
		articleService.removeByIds(Arrays.asList(ids));
        return R.ok();
    }
}
